using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Net;
using System.Net.Sockets;

namespace Travel.UserControls
{
    public partial class TestConnection : UserControl
    {
        IPEndPoint server;
        TcpClient tcpclient;
        int countTime;

        /// <summary>
        /// Gets control instance.
        /// This control can check the connection status between client and server.
        /// </summary>
        public TestConnection()
        {
            InitializeComponent();
            isDisconnect = false;
            isAuto = true;
        }

        private String serverIp;
        /// <summary>
        /// Ip of server you want to check connection.
        /// </summary>
        public String ServerIp
        {
            get { return serverIp; }
            set { serverIp = value; }
        }

        private int tcpport;
        /// <summary>
        /// Port of server.
        /// </summary>
        public int TCPPort
        {
            get { return tcpport; }
            set { tcpport = value; }
        }

        private int time;
        /// <summary>
        /// Time to auto reconnect to server.
        /// </summary>
        public int Time
        {
            get { return time; }
            set
            {
                time = value;
            }
        }

        private int range;
        /// <summary>
        /// Range between two times to check connection.
        /// More range, more not exactly status of server.
        /// But if it is to low. Server may be always busy.
        /// </summary>
        public int FrequenceTimeToCheckConnection
        {
            get { return range; }
            set { range = value; }
        }

        private bool isAuto;
        /// <summary>
        /// bool variable to set if control will auto connect after disconnect.
        /// </summary>
        public bool IsAutoReconnect
        {
            get { return isAuto; }
            set { isAuto = value; }
        }

        private bool isDisconnect;
        /// <summary>
        /// Status of control. User decide to disconnect to server.
        /// </summary>
        public bool IsDisconnect
        {
            get { return isDisconnect; }
            set { isDisconnect = value; }
        }

        private string userName;
        /// <summary>
        /// Username to connect to database.
        /// </summary>
        public string UserName
        {
            get { return userName; }
            set { userName = value; }
        }

        private string pass;
        /// <summary>
        /// Password to connect to database.
        /// </summary>
        public string Pass
        {
            get { return pass; }
            set { pass = value; }
        }

        private string database;
        /// <summary>
        /// Data base Name.
        /// </summary>
        public string DataBase
        {
            get { return database; }
            set { database = value; }
        }

        private int port;
        /// <summary>
        /// Port of database. Often is 3306.
        /// </summary>
        public int Port
        {
            get { return port; }
            set { port = value; }
        }

        /// <summary>
        /// Allow to check the connection to the server immediately.
        /// </summary>
        public void CheckServerImmediately()
        {
            StartCheckServer();
        }
        /// <summary>
        /// Check the status of server.
        /// </summary>
        private void StartCheckServer()
        {
            //Check if user decide to disconnect to server.
            if (!isDisconnect)
            {
                try
                {
                    //Start to check server in range.
                    watch.Enabled = true;
                    watchsecond.Enabled = false;
                    //prepare to connect to server.
                    server = new IPEndPoint(IPAddress.Parse(serverIp), tcpport);
                    tcpclient = new TcpClient();
                    //connect to server.
                    tcpclient.Connect(server);
                    //check the status of server.
                    if (tcpclient.Connected)
                    {
                        connectSymbol.Image = Travel.Resource1.big_connect;
                        connectSymbol.ContextMenuStrip = contextMenuConnect;
                    }
                    //close connection after check.
                    tcpclient.Close();
                }
                catch {
                    //change image of control
                    connectSymbol.Image = Travel.Resource1.big_disconnect;
                    //change contextStrip between connect and disconnect.
                    connectSymbol.ContextMenuStrip = contextMenuDisconnect;
                    //set time to auto reconnect.
                    countTime = time;
                    //stop check server in range.
                    watch.Enabled = false;
                    //begin to check immediately.
                    //in thi check there flag to check if auto or not.
                    watchsecond.Enabled = true;
                }
            }
        }
        /// <summary>
        /// Timer run every second to do in time have set.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void watchsecond_Tick(object sender, EventArgs e)
        {
            //user not allow to auto reconnect.
            if (!isAuto)
            {
                watchsecond.Enabled = false;
                return;
            }
            //begin to connect after time have set.
            if (countTime == 0)
            {
                StartCheckServer();
                countTime = time;
            }
            //begin to count down.
            countTime--;
            AutoReconnectConnect.Text = "Auto Reconnect : " + countTime + "sec";
        }
        /// <summary>
        /// Connect to server immediately.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Connect_Click(object sender, EventArgs e)
        {
            isDisconnect = false;
            StartCheckServer();
        }
        /// <summary>
        /// Disconnect to server immediately.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Disconnect_Click(object sender, EventArgs e)
        {
            tcpclient.Close();
            isDisconnect = true;
            connectSymbol.ContextMenuStrip = contextMenuDisconnect;
            connectSymbol.Image = Travel.Resource1.big_disconnect;
            AutoReconnectConnect.Text = "Auto Reconnect";
        }
        /// <summary>
        /// LoadConfig and check the status of connection of server.
        /// Often call at the first time class create.
        /// </summary>
        public void StartToCheck()
        {
            loadConfig();
            CheckServerImmediately();
        }
        /// <summary>
        /// Load config from file App.config
        /// </summary>
        private void loadConfig()
        {
            try
            {
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                serverIp = config.AppSettings.Settings["ServerIP"].Value;
                tcpport = Int32.Parse(config.AppSettings.Settings["TCPPort"].Value);
                userName = config.AppSettings.Settings["Username"].Value;
                pass = config.AppSettings.Settings["Pass"].Value;
                database = config.AppSettings.Settings["Database"].Value;
                port = Int32.Parse(config.AppSettings.Settings["Port"].Value);
                range = Int32.Parse(config.AppSettings.Settings["TimeOut"].Value);
                time = Int32.Parse(config.AppSettings.Settings["Time"].Value);
                watch.Interval = range;
                watch.Enabled = true;
                isAuto = true;
            }
            catch { }
        }

        /// <summary>
        /// Clock run during the application.
        /// Every cycle, this control will check the server status.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void watch_Tick(object sender, EventArgs e)
        {
            StartCheckServer();
        }

        /// <summary>
        /// Check or uncheck autoreconnect of disconnect menustrip.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AutoReconnectDisconnect_Click(object sender, EventArgs e)
        {
            CheckUnCheckAutoReconnect();
        }

        /// <summary>
        /// Check or uncheck autoreconnect of connect menustrip.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AutoReconnectConnect_Click(object sender, EventArgs e)
        {
            CheckUnCheckAutoReconnect();
        }

        /// <summary>
        /// Change the status of auto reconnect.
        /// </summary>
        private void CheckUnCheckAutoReconnect()
        {
            if (isAuto)
            {
                isAuto = false;
                AutoReconnectConnect.Image = Travel.Resource1.checkbox_no;
                AutoReconnectDisconnect.Image = Travel.Resource1.checkbox_no;
            }
            else
            {
                isAuto = true;
                AutoReconnectConnect.Image = Travel.Resource1.checkbox_yes;
                AutoReconnectDisconnect.Image = Travel.Resource1.checkbox_yes;
                StartCheckServer();
            }
        }

        /// <summary>
        /// Show the configuration form when disconnect to server.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ConfigureDisconnect_Click(object sender, EventArgs e)
        {
            new ConfigureForm().ShowDialog();
        }

        /// <summary>
        /// show the configuration form when still connect to server.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ConfigureConnect_Click(object sender, EventArgs e)
        {
            new ConfigureForm().ShowDialog();
        }
    }
}
